package cn.fx.framework.security;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;

/**
 * MD5Util 密文摘要生成
 * 1、字符串生成密文摘要
 * 2、字节数组生成密文摘要
 * 3、文件生成密文摘要
 * @author fxcn
 * @since 2024-9-23
 */
public class MD5Util {
	private static final String hexDigits[] = { "0", "1", "2", "3", "4", "5","6", "7", "8", "9", "a", "b", "c", "d", "e", "f" };
	private static String byteArrayToHexString(byte b[]) {
		StringBuffer resultSb = new StringBuffer();
		for (int i = 0; i < b.length; i++)
			resultSb.append(byteToHexString(b[i]));

		return resultSb.toString();
	}

	private static String byteToHexString(byte b) {
		int n = b;
		if (n < 0)
			n += 256;
		int d1 = n / 16;
		int d2 = n % 16;
		return hexDigits[d1] + hexDigits[d2];
	}

	/**
	 * MD5 字符串生成密文摘要
	 * @param origin 原内容
	 * @return MD5密文摘要
	 */
	public static String MD5Encode(String origin){
		return MD5Encode(origin, StandardCharsets.UTF_8);
	}

	/**
	 * MD5 字符串生成密文摘要
	 * @param origin 原内容
	 * @param charset 字符集
	 * @return MD5密文摘要
	 */
	public static String MD5Encode(String origin, Charset charset){
		return MD5Encode(origin, charset, null);
	}

	/**
	 * MD5 字符串生成密文摘要
	 * @param origin 原内容
	 * @param charset 字符集
	 * @param salt 盐值：增加复杂度与差异性
	 * @return MD5密文摘要
	 */
	public static String MD5Encode(String origin, Charset charset, String salt) {
		String resultString = null;
		try {
			resultString = new String(origin+salt);
			MessageDigest md = MessageDigest.getInstance("MD5");
			if (charset == null)
				resultString = byteArrayToHexString(md.digest(resultString
						.getBytes()));
			else
				resultString = byteArrayToHexString(md.digest(resultString
						.getBytes(charset)));
		} catch (Exception exception) {
		}
		return resultString;
	}

	/**
	 * MD5 字节数组生成密文摘要
	 * @param bytes 原始内容
	 * @return
	 */
	public static final String MD5Encode(byte[] bytes) {
		try {
			MessageDigest digest = MessageDigest.getInstance("MD5");
			byte[] buffer = new byte[1024];
			ByteArrayInputStream bIn = new ByteArrayInputStream(bytes);

			int len;
			while((len = bIn.read(buffer, 0, 1024)) != -1) {
				digest.update(buffer, 0, len);
			}

			bIn.close();
			return byteArrayToHexString(digest.digest());
		} catch (Exception var5) {
			return null;
		}
	}

	/**
	 * MD5 文件生成密文摘要
	 * @param file
	 * @return
	 */
	public static final String MD5Encode(File file) {
		FileInputStream in = null;
		byte[] buffer = new byte[1024];

		try {
			MessageDigest digest = MessageDigest.getInstance("MD5");
			in = new FileInputStream(file);

			int len;
			while((len = in.read(buffer, 0, 1024)) != -1) {
				digest.update(buffer, 0, len);
			}

			in.close();
			byte[] b = digest.digest();
			return byteArrayToHexString(b);
		} catch (Exception var6) {
			return null;
		}
	}

	public static void main(String[] args) {
/*
		System.out.println(MD5Util.MD5Encode("MD5Util 默认调用方法"));
		System.out.println(MD5Util.MD5Encode("MD5Util 字节数组生成密文摘要调用".getBytes(StandardCharsets.UTF_8)));

		File file = new File("C:\\Users\\Administrator\\Pictures\\80630.jpg");
		System.out.println(MD5Util.MD5Encode(file));
		*/
	}

}
